package com.whfp.coky.ble.listener

import android.util.Log
import com.clj.fastble.BleManager
import com.clj.fastble.callback.BleNotifyCallback
import com.clj.fastble.callback.BleWriteCallback
import com.clj.fastble.exception.BleException
import com.whfp.afs330h_sdk.callback.BaseNotifyCallback
import com.whfp.afs330h_sdk.utils.RxHexTool
import com.whfp.afs330h_sdk.zx
import com.whfp.coky.ble.model.PhyEviModel
import com.whfp.coky.ui.base.BaseActivity
import com.whfp.coky.utils.LogUtil

/**
 *
 *
 * created by coky on 2022/4/8
 */
abstract class WzxListener(val activity: BaseActivity<*, *>) : BaseNotifyCallback {

    private var currCommand: String = PhyEviModel.instruction1//当前指令

//    指令重发次数
    private var reSendTimes = 0
    private var RESEND_MAX = 3


    //    id相关
    private var currIndex_ID: Int = 0//物证箱id过大，分多包接收处理
    private var totalSum_ID: Int = 0//物证箱id总包大小
    private var totalLength_ID: Int = 0//物证箱id总长度
    private var data_ID = StringBuilder()//物证箱id拼接原始值

    var ID:String = ""//设备id

    override fun notifySuccess() {
        sendCode(PhyEviModel.instruction1)
    }


    override fun notifyFailure(var1: BleException?) {
        activity.toast("开启通知失败..")
        activity.finish()
    }

    override fun characteristicChanged(bytes: ByteArray?) {
//        hexhTool
        handleReceive(RxHexTool.formatHexString(bytes))
    }


    override fun writeFailure(exception: BleException?) {
//        发送 失败，重发
        reSend()
    }

    //    ---------------------------指令相关------------------------------------
    private fun handleReceive(str: String) {//消息接收
        if (RxHexTool.isWxzData(str)) {
            when (str.substring(0, 4)) {
                PhyEviModel.instruction1 -> obtainId(str)
                PhyEviModel.instruction2 -> obtainStatus(str)
                PhyEviModel.instruction3 -> obtainOpenStatus(str)
                PhyEviModel.instruction5 -> obtainTransStatus(str)
                else -> obtainIdPlus(str)
            }
        }
    }



    private fun obtainId(str: String) {//获取设备id
        currIndex_ID++
        totalSum_ID = RxHexTool.hexToDecimal(str.substring(6,8))
        totalLength_ID = RxHexTool.hexToDecimal(str.substring(8,10))
        LogUtil.e("totalSum_ID:$totalSum_ID,totalLength_ID:$totalLength_ID")
        data_ID.append(str.substring(10,str.length-2))
    }

    private fun obtainIdPlus(str: String) {//继续增加id
        currIndex_ID++
        data_ID.append(str.substring(0,str.length-2))
        LogUtil.e("data_ID.length:${data_ID.length},totalLength_ID:$totalLength_ID")
        if (currIndex_ID == totalSum_ID&&data_ID.length == totalLength_ID*2){
            initIDParmas()
            ID = data_ID.toString()

            LogUtil.e("ID:$ID")
            inputID(ID)
            sendCode(PhyEviModel.instruction2)//获取物证箱状态
        }
    }

    fun initIDParmas(){//初始化所有id相关参数
        currIndex_ID = 0
        totalSum_ID = 0
        totalLength_ID = 0
    }

    private fun obtainStatus(data: String) {//获取到设备状态
        activity.hideDialog()
        inputStatus(PhyEviModel.StatusBean().apply {
            this.pwr = data.substring(8, 10)
            this.db = data.substring(10, 11)
            this.jd = data.substring(12, 20)
            this.wd = data.substring(20, 28)
            this.s0 = data.substring(28, 30)
            this.s1 = data.substring(30, 32)
            this.s2 = data.substring(32, 34)
        })
    }

    private fun obtainOpenStatus(data: String) {//获取到开箱状态
        activity.hideDialog()
        when(data.substring(10, 12)){
            PhyEviModel.OPEN_SUCCESS->activity.toast("开箱成功！")
            PhyEviModel.OPEN_FAILED->activity.toast("开箱失败！")
            else ->activity.toast("未知错误！")
        }
    }

    private fun obtainTransStatus(data: String) {//获取到押运状态
        activity.hideDialog()
        when(data.substring(10, 12)){
            PhyEviModel.TRANS_SUCCESS->activity.toast("设置押运成功！")
            PhyEviModel.TRANS_FAILED->activity.toast("设置押运失败，已处于押运状态！")
            else ->activity.toast("未知错误！")
        }
    }


//    -----------------------------------指令发送---------------------------------
    //    重发
    private fun reSend() {
        activity.postDelayed({sendCode(currCommand)},200)
    }

    private fun sendCode(command: String) {
        var str = "指令发送中.."
        if (currCommand == command){//重发指令情况
            if (reSendTimes == RESEND_MAX){//重发多次情况
                activity.toast("多次发送失败，请重连..")
                zx.instance().currentDevice?.let {
                    zx.instance().disConnect(it)
                }
                return
            }else{//重传未超次数时，计数
                reSendTimes++
                str = "再次发送.."
            }
        }else{//发送其他指令时，重传次数归零
            reSendTimes = 0
        }
        activity.showDialog(str)
        currCommand = command
        when (currCommand) {
            PhyEviModel.instruction1 -> sendCode4Id()
            PhyEviModel.instruction2 -> sendCode4Sattus()
            PhyEviModel.instruction3 -> sendCode4OpenStatus()
            PhyEviModel.instruction5 -> sendCode4TransStatus()
        }
    }

    // 消息发送
    private fun sendCode4Id() {
        initIDParmas()
        write2Dev(PhyEviModel.buildIDCode())
    }

    private fun sendCode4Sattus() {

    }

    private fun sendCode4OpenStatus() {

    }

    private fun sendCode4TransStatus() {

    }


    fun write2Dev(data:String){
        zx.instance().currentDevice?.let {
            BleManager.getInstance().write(it,PhyEviModel.WZX_SERVICE_UUID,
            PhyEviModel.WZX_CHARACTERISTIC_WRITE_UUID, RxHexTool.hexStringToBytes(data),
                object :BleWriteCallback(){
                    override fun onWriteSuccess(i: Int, i1: Int, bytes: ByteArray?) {
                        Log.i(
                            "TAG",
                            "发送数据到设备成功！,当前第：" + i + "包数据，本机一共" + i1 + "包数据,正在发送的数据：" + RxHexTool.formatHexString(
                                bytes
                            )
                        )
                    }

                    override fun onWriteFailure(p0: BleException?) {
                       writeFailure(p0)
                    }

                }
            )
        }
    }

    //    -----------------------------启动监听----------------------------------------
    fun doOpenNotify() {
        BleManager.getInstance().notify(
            zx.instance().currentDevice, PhyEviModel.WZX_SERVICE_UUID,
            PhyEviModel.WZX_CHARACTERISTIC_NOTIFY_UUID, object : BleNotifyCallback() {
                override fun onNotifySuccess() {
                    notifySuccess()
                }

                override fun onNotifyFailure(p0: BleException?) {
                    notifyFailure(p0)
                }

                override fun onCharacteristicChanged(p0: ByteArray?) {
                    characteristicChanged(p0)
                }

            })
    }



//   abstract

    abstract fun inputID(str:String)

    abstract fun inputStatus(bean: PhyEviModel.StatusBean)
//    abstract fun ()
//    abstract fun inputStatus()
//    abstract fun inputStatus()


}